﻿#region License statement
// NJamb, a specification and delta-specification DSL
// Copyright (c) 2010-2011, Mark Knell
// Published under the MIT License; all other rights reserved
#endregion

#region using...
using NJamb.NUnit;
using NJamb.Parser.SpecificationBuilders.SubjectIs.Extensions;
using NJamb.Parser.SpecificationBuilders.SubjectIs.Simple.Singular;
using NJamb.Parser.SubjectBuilders;
using NJamb.Specifications.Delta;
using NJamb.Specifications.Simple.Singular;
using NUnit.Framework;
using Stile.Patterns.SelfDescribingPredicates;
using Stile.Readability;
#endregion

namespace NJamb.Tests.Parser.SpecificationBuilders.SubjectIs
{
    [TestFixture]
    public class IsExtensionsFixture : EvaluatingSampleFixture
    {
        [Test]
        public void GreaterThan()
        {
            Specify.For(() => _sample).That(x => x.Int).Is.EqualTo(1).AsPrecondition();
            // arrange
            ISingularSpecification<int> singularSpecification = Specify.For(() => _sample).That(x => x.Int).Is.GreaterThan(2);

            // act
            IEvaluation<int> evaluation = singularSpecification.Evaluate();

            // assert
            AssertEvaluationFailed(evaluation, "expected _sample.Int would be > 2", " but was 1.");
            AssertEvaluationFailed(Specify.For(() => _sample).That(x => x.Int).Is.Not.GreaterThan(0).Evaluate(),
                "expected _sample.Int would not be > 0",
                " but was 1.");
        }

        [Test]
        public void IsNull()
        {
            INegatableSingularIs<string> negatableSingularIs = Specify.For(() => _sample).That(x => x.String).Is;
            negatableSingularIs.EqualTo(Null.String).AsPrecondition();

            // arrange
            ISingularSpecification<string> singularSpecification = negatableSingularIs.Null();

            // act
            IEvaluation evaluation = singularSpecification.Evaluate();

            // assert
            Assert.That(evaluation.Success, Is.True);
            AssertEvaluationFailed(negatableSingularIs.Not.Null().Evaluate(),
                "expected _sample.String would not be \"<null>\"",
                " but was \"<null>\".");
        }

        [Test]
        public void IsNullDelta()
        {
            // arrange
            IPreconditionEvaluation preconditionEvaluation =
                Specify.For(() => _sample).That(x => x.String).Is.Null().AndLater.Is.Not.Null().EvaluatePrecondition();

            // act
            IEvaluation before = preconditionEvaluation.Evaluation;
            _sample.String = "q";
            IEvaluation after = preconditionEvaluation.GetPostcondition().Evaluate();

            // assert
            Assert.That(before.Success, Is.True);
            Assert.That(after.Success, Is.True);
        }

        [Test]
        public void NullOrEmpty()
        {
            INegatableSingularIs<string> negatableSingularIs = Specify.For(() => _sample).That(x => x.String).Is;
            negatableSingularIs.EqualTo(Null.String).AsPrecondition();

            // arrange
            ISingularSpecification<string> singularSpecification = negatableSingularIs.NullOrEmpty();

            // act
            IEvaluation evaluation = singularSpecification.Evaluate();

            // assert
            Assert.That(evaluation.Success, Is.True);

            // empty
            _sample.String = string.Empty;
            Assert.That(Specify.For(() => _sample).That(x => x.String).Is.NullOrEmpty().Evaluate().Success, Is.True);
        }

        [Test]
        public void NullOrWhitespace()
        {
            Specify.For(() => _sample).That(x => x.String).Is.EqualTo(Null.String).AsPrecondition();
            Assert.That(Specify.For(() => _sample).That(x => x.String).Is.NullOrWhitespace().Evaluate().Success, Is.True);

            _sample.String = "\t";

            Specify.For(() => _sample).That(x => x.String).Satisfies(x => string.IsNullOrWhiteSpace(x)).AsPrecondition();
            Assert.That(Specify.For(() => _sample).That(x => x.String).Is.NullOrWhitespace().Evaluate().Success, Is.True);
        }
    }
}
